Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Commit d493e5e311d1c7fcdf157a9ab1094d534c5417e9


Parents : 4f9cfee
Author : Mark Qvist <mark@adepta.io>
Date : 2018-06-27T11:42:48+02:00

Implemented LoRa promiscuous mode

Changes

3 files changed, 152 insertions(+), 66 deletions(-)

M Config.h +3 -1
M RNode_Firmware.ino +130 -65

Diff

diff --git a/Config.h b/Config.h
index 3452e6d..fdc8905 100644
--- a/Config.h
+++ b/Config.h
@@ -4,7 +4,7 @@
#define CONFIG_H
#define MAJ_VERS 0x01
- #define MIN_VERS 0x04
+ #define MIN_VERS 0x05
#define MCU_328P 0x90
#define MCU_1284P 0x91
@@ -77,6 +77,8 @@
bool radio_locked = true;
bool radio_online = false;
bool hw_ready = false;
+ bool promisc = false;
+
uint8_t op_mode = MODE_HOST;
uint8_t model = 0x00;
uint8_t hwrev = 0x00;

diff --git a/RNode_Firmware.ino b/RNode_Firmware.ino
index 7f629b9..6e6604f 100644
--- a/RNode_Firmware.ino
+++ b/RNode_Firmware.ino
@@ -89,53 +89,84 @@ void update_radio_lock() {
}
void receiveCallback(int packet_size) {
- uint8_t header = LoRa.read(); packet_size--;
- uint8_t sequence = packetSequence(header);
- bool ready = false;
-
- if (isSplitPacket(header) && seq == SEQ_UNSET) {
- // This is the first part of a split
- // packet, so we set the seq variable
- // and add the data to the buffer
- read_len = 0;
- seq = sequence;
- last_rssi = LoRa.packetRssi();
- getPacketData(packet_size);
- } else if (isSplitPacket(header) && seq == sequence) {
- // This is the second part of a split
- // packet, so we add it to the buffer
- // and set the ready flag.
- last_rssi = (last_rssi+LoRa.packetRssi())/2;
- getPacketData(packet_size);
- seq = SEQ_UNSET;
- ready = true;
- } else if (isSplitPacket(header) && seq != sequence) {
- // This split packet does not carry the
- // same sequence id, so we must assume
- // that we are seeing the first part of
- // a new split packet.
- read_len = 0;
- seq = sequence;
- last_rssi = LoRa.packetRssi();
- getPacketData(packet_size);
- } else if (!isSplitPacket(header)) {
- // This is not a split packet, so we
- // just read it and set the ready
- // flag to true.
-
- if (seq != SEQ_UNSET) {
- // If we already had part of a split
- // packet in the buffer, we clear it.
+ if (!promisc) {
+ // The standard operating mode allows large
+ // packets with a payload up to 500 bytes,
+ // by combining two raw LoRa packets.
+ // We read the 1-byte header and extract
+ // packet sequence number and split flags
+ uint8_t header = LoRa.read(); packet_size--;
+ uint8_t sequence = packetSequence(header);
+ bool ready = false;
+
+ if (isSplitPacket(header) && seq == SEQ_UNSET) {
+ // This is the first part of a split
+ // packet, so we set the seq variable
+ // and add the data to the buffer
read_len = 0;
+ seq = sequence;
+ last_rssi = LoRa.packetRssi();
+ getPacketData(packet_size);
+ } else if (isSplitPacket(header) && seq == sequence) {
+ // This is the second part of a split
+ // packet, so we add it to the buffer
+ // and set the ready flag.
+ last_rssi = (last_rssi+LoRa.packetRssi())/2;
+ getPacketData(packet_size);
seq = SEQ_UNSET;
+ ready = true;
+ } else if (isSplitPacket(header) && seq != sequence) {
+ // This split packet does not carry the
+ // same sequence id, so we must assume
+ // that we are seeing the first part of
+ // a new split packet.
+ read_len = 0;
+ seq = sequence;
+ last_rssi = LoRa.packetRssi();
+ getPacketData(packet_size);
+ } else if (!isSplitPacket(header)) {
+ // This is not a split packet, so we
+ // just read it and set the ready
+ // flag to true.
+
+ if (seq != SEQ_UNSET) {
+ // If we already had part of a split
+ // packet in the buffer, we clear it.
+ read_len = 0;
+ seq = SEQ_UNSET;
+ }
+
+ last_rssi = LoRa.packetRssi();
+ getPacketData(packet_size);
+ ready = true;
}
+ if (ready) {
+ // We first signal the RSSI of the
+ // recieved packet to the host.
+ Serial.write(FEND);
+ Serial.write(CMD_STAT_RSSI);
+ Serial.write((uint8_t)(last_rssi-rssi_offset));
+
+ // And then write the entire packet
+ Serial.write(FEND);
+ Serial.write(CMD_DATA);
+ for (int i = 0; i < read_len; i++) {
+ uint8_t byte = pbuf[i];
+ if (byte == FEND) { Serial.write(FESC); byte = TFEND; }
+ if (byte == FESC) { Serial.write(FESC); byte = TFESC; }
+ Serial.write(byte);
+ }
+ Serial.write(FEND);
+ read_len = 0;
+ }
+ } else {
+ // In promiscuous mode, raw packets are
+ // output directly over to the host
+ read_len = 0;
last_rssi = LoRa.packetRssi();
getPacketData(packet_size);
- ready = true;
- }
- if (ready) {
// We first signal the RSSI of the
// recieved packet to the host.
Serial.write(FEND);
@@ -152,7 +183,7 @@ void receiveCallback(int packet_size) {
Serial.write(byte);
}
Serial.write(FEND);
- read_len = 0;
+ read_len = 0;
}
}
@@ -216,39 +247,66 @@ void processQueue() {
void transmit(size_t size) {
if (radio_online) {
- led_tx_on();
- size_t written = 0;
- uint8_t header = random(256) & 0xF0;
+ if (!promisc) {
+ led_tx_on();
+ size_t written = 0;
+ uint8_t header = random(256) & 0xF0;
- if (size > SINGLE_MTU - HEADER_L) {
- header = header | FLAG_SPLIT;
- }
+ if (size > SINGLE_MTU - HEADER_L) {
+ header = header | FLAG_SPLIT;
+ }
- LoRa.beginPacket();
- LoRa.write(header); written++;
+ LoRa.beginPacket();
+ LoRa.write(header); written++;
- for (size_t i; i < size; i++) {
- #if QUEUE_SIZE > 0
- LoRa.write(tbuf[i]);
- #else
- LoRa.write(sbuf[i]);
- #endif
+ for (size_t i; i < size; i++) {
+ #if QUEUE_SIZE > 0
+ LoRa.write(tbuf[i]);
+ #else
+ LoRa.write(sbuf[i]);
+ #endif
- written++;
+ written++;
- if (written == 255) {
- LoRa.endPacket();
- LoRa.beginPacket();
- LoRa.write(header);
- written = 1;
+ if (written == 255) {
+ LoRa.endPacket();
+ LoRa.beginPacket();
+ LoRa.write(header);
+ written = 1;
+ }
}
- }
- LoRa.endPacket();
- led_tx_off();
+ LoRa.endPacket();
+ led_tx_off();
+
+ LoRa.receive();
+ } else {
+ // In promiscuous mode, we only send out
+ // plain raw LoRa packets with a maximum
+ // payload of 255 bytes
+ led_tx_on();
+ size_t written = 0;
+
+ // Cap packets at 255 bytes
+ if (size > SINGLE_MTU) {
+ size = SINGLE_MTU;
+ }
- LoRa.receive();
+ LoRa.beginPacket();
+ for (size_t i; i < size; i++) {
+ #if QUEUE_SIZE > 0
+ LoRa.write(tbuf[i]);
+ #else
+ LoRa.write(sbuf[i]);
+ #endif
+
+ written++;
+ }
+ LoRa.endPacket();
+ led_tx_off();
+ LoRa.receive();
+ }
} else {
kiss_indicate_error(ERROR_TXFAILED);
led_indicate_error(5);
@@ -400,6 +458,13 @@ void serialCallback(uint8_t sbyte) {
if (sbyte == DETECT_REQ) {
kiss_indicate_detect();
}
+ } else if (command == CMD_PROMISC) {
+ if (sbyte == 0x01) {
+ promisc_enable();
+ } else if (sbyte == 0x00) {
+ promisc_disable();
+ }
+ kiss_indicate_promisc();
} else if (command == CMD_UNLOCK_ROM) {
if (sbyte == ROM_UNLOCK_BYTE) {
unlock_rom();

diff --git a/Utilities.cpp b/Utilities.cpp
index ba8da4c..2722827 100644
--- a/Utilities.cpp
+++ b/Utilities.cpp
@@ -199,6 +199,17 @@ void kiss_indicate_ready() {
Serial.write(FEND);
}
+void kiss_indicate_promisc() {
+ Serial.write(FEND);
+ Serial.write(CMD_PROMISC);
+ if (promisc) {
+ Serial.write(0x01);
+ } else {
+ Serial.write(0x00);
+ }
+ Serial.write(FEND);
+}
+
void kiss_indicate_detect() {
Serial.write(FEND);
Serial.write(CMD_DETECT);
@@ -278,6 +289,14 @@ uint8_t getRandom() {
}
}
+void promisc_enable() {
+ promisc = true;
+}
+
+void promisc_disable() {
+ promisc = false;
+}
+
bool eeprom_info_locked() {
uint8_t lock_byte = EEPROM.read(eeprom_addr(ADDR_INFO_LOCK));
if (lock_byte == INFO_LOCK_BYTE) {


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────